package com.redstars.generate.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.redstars.generate.config.DbStatusEnum;
import com.redstars.generate.config.GenDataSource;
import com.redstars.generate.convert.SysTableConvert;
import com.redstars.generate.entity.SysDatasource;
import com.redstars.generate.entity.SysTable;
import com.redstars.generate.exception.RedstarsException;
import com.redstars.generate.page.PageResult;
import com.redstars.generate.result.Result;
import com.redstars.generate.utils.DbUtils;
import com.redstars.generate.utils.GenUtils;
import com.redstars.generate.utils.PageUtils;
import com.redstars.generate.vo.SysTableVo;
import lombok.AllArgsConstructor;
import com.redstars.generate.convert.SysDatasourceConvert;
import com.redstars.generate.query.SysDatasourceQuery;
import com.redstars.generate.vo.SysDatasourceVo;
import com.redstars.generate.dao.SysDatasourceDao;
import com.redstars.generate.service.SysDatasourceService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;

import javax.sql.DataSource;

/**
 * 数据源管理
 *
 * @author zhouhx 
 * @since 1.0.0 2022-10-05
 */
@Service
@AllArgsConstructor
public class SysDatasourceServiceImpl extends ServiceImpl<SysDatasourceDao, SysDatasource> implements SysDatasourceService {
    private final DataSource dataSource;

    @Override
    public PageResult<SysDatasourceVo> page(SysDatasourceQuery query) {
        LambdaQueryWrapper<SysDatasource> wrapper = getWrapper(query);
        PageUtils<SysDatasource> pageUtils = new PageUtils<>();
        IPage<SysDatasource> page = this.page(pageUtils.getPage(query), wrapper);
//        if(CollUtil.isNotEmpty(page.getRecords())){
//            page.getRecords().forEach(row ->{
//                try {
//                    DbUtils.getConnection(new GenDataSource(row));
//                    row.setStatus(DbStatusEnum.SUCCESS.getCode());
//                } catch (Exception e) {
//                    log.error(e.getMessage(), e);
//                    row.setStatus(DbStatusEnum.FAIL.getCode());
//                }
//            });
//        }

        return pageUtils.getPageData(page,SysDatasourceVo.class);
    }

    private LambdaQueryWrapper<SysDatasource> getWrapper(SysDatasourceQuery query){
        LambdaQueryWrapper<SysDatasource> wrapper = Wrappers.lambdaQuery();

        return wrapper;
    }

    @Override
    public void save(SysDatasourceVo vo) {
        SysDatasource entity = SysDatasourceConvert.INSTANCE.convert(vo);

        baseMapper.insert(entity);
    }

    @Override
    public void update(SysDatasourceVo vo) {
        SysDatasource entity = SysDatasourceConvert.INSTANCE.convert(vo);

        updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> idList) {
        removeByIds(idList);
    }

    @Override
    public SysDatasourceVo detail(Long id) {
        SysDatasource detail = this.getById(id);
        if (ObjectUtil.isEmpty(detail)) {
        throw new RedstarsException("记录不存在");
        }
        return BeanUtil.copyProperties(detail,SysDatasourceVo.class);
    }

    @Override
    public Result<String> test(Long id) {
        try {
            SysDatasource entity = this.getById(id);

            DbUtils.getConnection(new GenDataSource(entity));
            return Result.ok("连接成功");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("连接失败，请检查配置信息");
        }
    }

    @Override
    public List<SysDatasourceVo> list(SysDatasourceQuery query) {
        LambdaQueryWrapper<SysDatasource> wrapper = getWrapper(query);

        List<SysDatasource> list = this.list(wrapper);
        return SysDatasourceConvert.INSTANCE.convertList(list);
    }

    @Override
    public Result<List<SysTableVo>> tableList(Long id) {
        try {
            // 获取数据源
            GenDataSource datasource = this.get(id);
            // 根据数据源，获取全部数据表
            List<SysTable> tableList = GenUtils.getTableList(datasource);

            return Result.ok(SysTableConvert.INSTANCE.convertList(tableList));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("数据源配置错误，请检查数据源配置！");
        }
    }

    @Override
    public String getDatabaseProductName(Long datasourceId) {
        return null;
    }

    @Override
    public GenDataSource get(Long datasourceId) {
        // 初始化配置信息
        GenDataSource info = null;
        if (datasourceId.intValue() == 0) {
            try {
                info = new GenDataSource(dataSource.getConnection());
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else {
            info = new GenDataSource(this.getById(datasourceId));
        }

        return info;
    }

    @Override
    public Result<List<SysTableVo>> tableList(Long id, String tableName) {
        try {
            // 获取数据源
            GenDataSource datasource = this.get(id);
            // 根据数据源，获取全部数据表
            List<SysTable> tableList = GenUtils.getTableList(datasource);
            if(StrUtil.isNotBlank(tableName) && CollUtil.isNotEmpty(tableList)){
                tableList = tableList.stream().filter(table -> table.getTableName().contains(tableName)).collect(Collectors.toList());
            }
            return Result.ok(SysTableConvert.INSTANCE.convertList(tableList));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("数据源配置错误，请检查数据源配置！");
        }
    }

}